/*
--------------------------------------------------------------------------------
				Ak-Lib. 
			 Project       	: Ak-Lib
			 Group         	: Ak-Lib R&D Team
			 Author        	: Ocean.Wang
			 Create Date 	: 05-01-2010
--------------------------------------------------------------------------------
Code Name 	:  A.K 	~v~
Description	:  Yet Another Cross-Platform Lib.
Cautions    	:
--------------------------------------------------------------------------------
Change History:
Version		: 0.1
Building 		: 05/01/10
10-05.01 first draft, build, debug and test.
--------------------------------------------------------------------------------
*/

#ifndef _INC_AK_IE_
#define	_INC_AK_IE_

#include "ak_types.h"
#include "ak_queue.h"
#include "ak_lock.h"
#include "ak_mem.h"

#ifdef __cplusplus
extern "C" {
#endif


/* The Common Infor Element : Used by Msg, Event, Object 
** 1. IE-Pool
**	Normally, the Dynamic IE is alloced from Pool. When Fini, will check whether the mType is Dynamic,
**	the Dynamic IE could be auto-free.
** 2. IE-Union
**	the Value could be as an union. 
**	2.1 simple & basic vaule type.
**	2.2 complex, use the Pointer.
**	2.3 cache, for small struct, an aligned-cacheline size storage is supported.
**	User should be careful not to overflow it.
*/
#define _sIE_CacheSz 		0X18	

/* IE's Memory Type Define */
#define _sIE_MT_STATIC 		0X00
#define _sIE_MT_DYNAMIC 	0X01
#define _sIE_MT_EX		 	0X02

/* IE's Value Type Define */
#define _sIE_VT_NULL 		0X00

#define _sIE_VT_S32 		0X01
#define _sIE_VT_U32 		0X02

#define _sIE_VT_S64 		0X03
#define _sIE_VT_U64 		0X04

#define _sIE_VT_MSG 		0X05
#define _sIE_VT_CACHE 		0X06
#define _sIE_VT_CB 			0X07

typedef struct{
	unsigned int	len;
	unsigned int	reserv;
	void *			ptr;	/* Msg Ptr */
	void *			pool;	/* Maybe Null */
}_t_sIEMsg;

/* The Container of the IE */
typedef struct{
	unsigned char	mType; 	/* Memory Type, Static: No Need to Free. Dynamic: Need to Free */
	unsigned char	vType; 	/* Value Type */
	unsigned short	sParam;	/* Parameter Short, 	16bit.	EPri		*/
	unsigned int	iParam;	/* Parameter Int, 		32bit. 	EType 	*/

	/* ooOps : the IE Union */
	union{
		int 				s32;
		unsigned int		u32;
		long long			s64;
		unsigned long long	u64;

		/* Complex & Dynamic IE will Use the Pointer, Adding the Pool Ref */
		_t_sIEMsg 			msg;	/* For Static & Dynamic Ptr */
		
		/* Custom */
		unsigned char		cache[_sIE_CacheSz];	/* Be-Careful to use the cache for small storage */
		_t_cbentry			cb; 					/* Dangerous */
	};
}_t_sIECont;


/* The Information Element */
typedef union {
	/* Content */
	_t_sIECont				cont;
	unsigned long long 		llFake[4];			/* The fake 32 bytes */
}_t_sIE;

/* Marcos for IE's Init /Set */
#define _SIE_Init(pIE)\
do{\
	(pIE)->llFake[0] = 0;\
	(pIE)->llFake[1] = 0;\
	(pIE)->llFake[2] = 0;\
	(pIE)->llFake[3] = 0;\
}while(0)

#define _SIE_Set(pDst, pSrc)\
do{\
	(pDst)->llFake[0] = (pSrc)->llFake[0];\
	(pDst)->llFake[1] = (pSrc)->llFake[1];\
	(pDst)->llFake[2] = (pSrc)->llFake[2];\
	(pDst)->llFake[3] = (pSrc)->llFake[3];\
}while(0)

#define _SIE_SetParam(pDst, pSrc)\
do{\
	(pDst)->cont.sParam = (pSrc)->cont.sParam;\
	(pDst)->cont.iParam = (pSrc)->cont.iParam;\
}while(0)

#define _SIE_SetMType(pDst, typeM)\
do{\
	(pDst)->cont.mType = typeM;\
}while(0)

#define _SIE_SetVType(pDst, typeV)\
do{\
	(pDst)->cont.vType = typeV;\
}while(0)

#define _SCont_SetMsg(pCont, typeM, pMsg, lMsg, mPool) \
do{\
	(pCont)->mType = typeM;\
	(pCont)->vType = _sIE_VT_MSG;\
	(pCont)->msg.ptr = (void *		)(pMsg);\
	(pCont)->msg.len = (unsigned int)(lMsg);\
	(pCont)->msg.pool= (void *		)(mPool);\
}while(0)

#define _SCont_SetVal(pCont, vT, value) \
do{\
	(pCont)->vT = value;\
}while(0)




#ifdef __cplusplus
}
#endif

#endif




